package com.easylinkin.linkappapi.safe.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.easylinkin.linkappapi.annotation.CommonOperateLogAnnotate;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.common.utils.excel.ExcelConstant;
import com.easylinkin.linkappapi.common.utils.excel.ExcelTools;
import com.easylinkin.linkappapi.common.utils.io.OutputStreamUtil;
import com.easylinkin.linkappapi.operatelog.LogHelper;
import com.easylinkin.linkappapi.operatelog.constant.LogConstant.LogModule;
import com.easylinkin.linkappapi.operatelog.constant.LogConstant.LogOperateType;
import com.easylinkin.linkappapi.safe.dto.HiddenDangerCountDTO;
import com.easylinkin.linkappapi.safe.dto.HiddenDangerDTO;
import com.easylinkin.linkappapi.safe.entity.HiddenDanger;
import com.easylinkin.linkappapi.safe.service.HiddenDangerService;
import io.swagger.annotations.ApiOperation;
import jodd.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * HiddenDanger表控制层
 *
 * @author CodeGenerator
 * @date 2022/07/21
 */
@RestController
@RequestMapping("hiddenDanger")
public class HiddenDangerController extends ApiController {
	/**
	 * 服务对象
	 */
	@Resource
	private HiddenDangerService hiddenDangerService;

	/**
	 * 分页查询所有数据
	 *
	 * @param requestModel 查询分页对象
	 * @return 所有数据
	 */
	@PostMapping("getPage")
	@ApiOperation("查询分页")
	public RestMessage selectPage(@RequestBody RequestModel<HiddenDangerDTO> requestModel) {
		Assert.notNull(requestModel.getCustomQueryParams(), "customQueryParams 不能为空");
		Assert.notNull(requestModel.getPage(), "page 不能为空");

		IPage<HiddenDangerDTO> record = hiddenDangerService.selectListByPage(requestModel.getPage(),
				requestModel.getCustomQueryParams());

		return RestBuilders.successBuilder(record).build();
	}

	/**
	 * 通过主键查询单条数据
	 *
	 * @param id 主键
	 * @return 单条数据
	 */
	@GetMapping("{id}")
	@ApiOperation("查询单条")
	public RestMessage selectOne(@PathVariable Serializable id) {
		return RestBuilders.successBuilder((this.hiddenDangerService.getOneById(id))).build();
	}

	/**
	 * 新增数据
	 *
	 * @param hiddenDanger 实体对象
	 * @return 新增结果
	 */
	@PostMapping("add")
	@ApiOperation("新增")
	public RestMessage insert(@RequestBody HiddenDanger hiddenDanger) {
		return RestBuilders.successBuilder((this.hiddenDangerService.saveOne(hiddenDanger))).build();
	}

	/**
	 * 修改数据
	 *
	 * @param hiddenDanger 实体对象
	 * @return 修改结果
	 */
	@PutMapping
	@ApiOperation("修改单条")
	public RestMessage update(@RequestBody HiddenDanger hiddenDanger) {
		return RestBuilders.successBuilder().success(this.hiddenDangerService.updateOne(hiddenDanger)).build();
	}

  /**
   * 修改整改人
   *
   * @param hiddenDanger 实体对象
   * @return 修改结果
   */
  @PostMapping("modifyRectifyUser")
  @ApiOperation("修改整改人")
  public RestMessage modifyRectifyUser(@RequestBody HiddenDanger hiddenDanger) {
    return RestBuilders.successBuilder()
        .success(this.hiddenDangerService.modifyRectifyUser(hiddenDanger)).build();
  }

  /**
   * 修改复查人
   *
   * @param hiddenDanger 实体对象
   * @return 修改结果
   */
  @PostMapping("modifyCheckUser")
  @ApiOperation("修改整改人")
  public RestMessage modifyCheckUser(@RequestBody HiddenDanger hiddenDanger) {
    return RestBuilders.successBuilder()
        .success(this.hiddenDangerService.modifyCheckUser(hiddenDanger)).build();
  }

	/**
	 * 删除数据
	 *
	 * @param idList 主键结合
	 * @return 删除结果
	 */
	@DeleteMapping
	@ApiOperation("批量删除")
	@CommonOperateLogAnnotate(module = LogModule.SAFE_MANAGEMENT, desc = "")
	public RestMessage delete(@RequestParam("idList") List<String> idList) {
		// 记录日志详情
		List<String> hiddenDangers = new ArrayList<>();
		idList.forEach(p->{
			HiddenDangerDTO hiddenDangerDTO = this.hiddenDangerService.getOneById(p);
			hiddenDangers.add(hiddenDangerDTO.getContent());
		});
		if(CollectionUtil.isNotEmpty(hiddenDangers)){
			LogHelper.setContent(LogOperateType.SAFE_HIDDEN_DANGER_DELETE, StringUtil.join(hiddenDangers,","));
		}
		return RestBuilders.successBuilder().success(this.hiddenDangerService.deleteByIds(idList)).build();
	}

	@PostMapping("export")
	@ApiOperation("导出")
	public void export(@RequestBody HiddenDanger hiddenDanger, HttpServletRequest request,
			HttpServletResponse response) {
		hiddenDangerService.export(hiddenDanger, request, response);
	}

	/**
	 * 获取检查台账首页统计
	 * 
	 * @return
	 */
	@GetMapping("getCount")
	@ApiOperation("检查台账首页统计")
	public RestMessage getCount(@RequestParam(value = "content",required = false) String content,
								@RequestParam(value = "linkUnitId",required = false) String linkUnitId, @RequestParam(value = "rectifyUid",required = false) Long rectifyUid,
								@RequestParam(value = "startTime",required = false) String startTime, @RequestParam(value = "endTime",required = false) String endTime, @RequestParam(value = "tenantId",required = false)String tenantId) {
		Date startTimeDate = null;
		Date endTimeDate = null;
		if (StringUtils.isNotBlank(startTime)){
			startTimeDate = DateUtil.parseDateTime(startTime);
		}
		if (StringUtils.isNotBlank(endTime)){
			endTimeDate = DateUtil.parseDateTime(endTime);
		}
		HiddenDangerCountDTO countDto = this.hiddenDangerService.getCount(content,linkUnitId,rectifyUid,startTimeDate,endTimeDate,tenantId);

		return RestBuilders.successBuilder(countDto).build();
	}

	/**
	 * 获取检查台账首页统计
	 * @return
	 */
	@GetMapping("getUnitIdCount")
	@ApiOperation("检查台账按参建单位维度统计")
	public RestMessage getUnitIdCount(@RequestParam(value = "startTime",required = false) String startTime, @RequestParam(value = "endTime",required = false) String endTime, @RequestParam(value = "tenantId",required = false)String tenantId) {
		Date startTimeDate = null;
		Date endTimeDate = null;
		if (StringUtils.isNotBlank(startTime)){
			startTimeDate = DateUtil.parseDateTime(startTime);
		}
		if (StringUtils.isNotBlank(endTime)){
			endTimeDate = DateUtil.parseDateTime(endTime);
		}
		List<HiddenDangerCountDTO> unitIdCount = this.hiddenDangerService.getUnitIdCount(startTimeDate,endTimeDate,tenantId);
		return RestBuilders.successBuilder(unitIdCount).build();
	}

	/**
	 * 获取检查台账首页统计
	 *
	 * @return
	 */
	@GetMapping("getTypeCount")
	@ApiOperation("检查台账按类别维度统计")
	public RestMessage getTypeCount(@RequestParam(value = "startTime",required = false) String startTime, @RequestParam(value = "endTime",required = false) String endTime, @RequestParam(value = "tenantId",required = false)String tenantId) {
		Date startTimeDate = null;
		Date endTimeDate = null;
		if (StringUtils.isNotBlank(startTime)){
			startTimeDate = DateUtil.parseDateTime(startTime);
		}
		if (StringUtils.isNotBlank(endTime)){
			endTimeDate = DateUtil.parseDateTime(endTime);
		}
		List<HiddenDangerCountDTO> unitIdCount = this.hiddenDangerService.getTypeCount(startTimeDate,endTimeDate,tenantId);
		return RestBuilders.successBuilder(unitIdCount).build();
	}

	/**
	 * 获取检查台账首页统计
	 *
	 * @return
	 */
	@GetMapping("getPartCount")
	@ApiOperation("检查台账按检查部位维度统计")
	public RestMessage getPartCount(@RequestParam(value = "startTime",required = false) String startTime
			, @RequestParam(value = "endTime",required = false) String endTime
			, @RequestParam(value = "tenantId",required = false) String tenantId) {
		Date startTimeDate = null;
		Date endTimeDate = null;
		if (StringUtils.isNotBlank(startTime)){
			startTimeDate = DateUtil.parseDateTime(startTime);
		}
		if (StringUtils.isNotBlank(endTime)){
			endTimeDate = DateUtil.parseDateTime(endTime);
		}
		List<HiddenDangerCountDTO> unitIdCount = this.hiddenDangerService.getPartCount(startTimeDate, endTimeDate,tenantId);
		return RestBuilders.successBuilder(unitIdCount).build();
	}

	/**
	 * 获取检查台账首页统计
	 *
	 * @return
	 */
	@GetMapping("getPersonCount")
	@ApiOperation("检查台账按人员维度统计")
	public RestMessage getPersonCount() {
		List<HiddenDangerCountDTO> unitIdCount = this.hiddenDangerService.getPersonCount();
		return RestBuilders.successBuilder(unitIdCount).build();
	}

	@GetMapping("getMonthCount")
	@ApiOperation("检查台账按月维度统计")
	public RestMessage getMonthCount() {
		List<JSONObject> result = new ArrayList<>();
		List<HiddenDangerCountDTO> unitIdCount = this.hiddenDangerService.getMonthCount();
		if(CollectionUtil.isNotEmpty(unitIdCount)){
			Map<String, List<HiddenDangerCountDTO>> collect = unitIdCount.stream()
					.collect(Collectors.groupingBy(HiddenDangerCountDTO::getCreateTimeStr));
			//进行排序
			List<String> strList = new ArrayList();
			strList.addAll(collect.keySet());
			Collections.sort(strList, new Comparator<String>() {
				@Override
				public int compare(String o1, String o2) {
					return o1.compareTo(o2);
				}
			});
			for (String key : strList) {
				List<HiddenDangerCountDTO> hiddenDangerCountDTOS = collect.get(key);
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("time",key);
				for (HiddenDangerCountDTO dto : hiddenDangerCountDTOS){
					if(Integer.valueOf("1").equals(dto.getLevel())){
						jsonObject.put("level1",dto.getTotalNum());
					}
					if(Integer.valueOf("2").equals(dto.getLevel())){
						jsonObject.put("level2",dto.getTotalNum());
					}
					if(Integer.valueOf("3").equals(dto.getLevel())){
						jsonObject.put("level3",dto.getTotalNum());
					}
					if(Integer.valueOf("4").equals(dto.getLevel())){
						jsonObject.put("level4",dto.getTotalNum());
					}
				}
				result.add(jsonObject);
			}
		}
		return RestBuilders.successBuilder(result).build();
	}

	@GetMapping("getDayCount")
	@ApiOperation("检查台账按天维度统计")
	public RestMessage getDayCount() {
		List<HiddenDangerCountDTO> unitIdCount = this.hiddenDangerService.getDayCount();
		return RestBuilders.successBuilder(unitIdCount).build();
	}

	@GetMapping("my")
	@ApiOperation("检查台账按天维度统计")
	public RestMessage getMyCount(){
		HiddenDangerCountDTO countDto = this.hiddenDangerService.getMyCount();
		return RestBuilders.successBuilder(countDto).build();
	}

	//导出检查记录表
	//整改通知书
	/**
	 * @Description: 导出检查记录表/整改通知书
	 * @author kan yuanfeng
	 * @date 2020/11/04 11:42
	 */
	@GetMapping("exportWord/{type}")
	@ApiOperation("导出检查记录表/整改通知书")
	@CommonOperateLogAnnotate(module = LogModule.SAFE_MANAGEMENT, desc = "")
	public void exportById(@RequestHeader("User-Agent") String header,HttpServletResponse response,
			@PathVariable("type")Integer type,Integer wordType,@RequestParam("ids") List<String> ids)
			throws Exception {
		if (type != null){
			if(type.intValue() == 1){
				LogHelper.setContent(LogOperateType.SAFE_MANAGEMENT_EXPORT_INSPECTION_RECORDS);
			}else{
				LogHelper.setContent(LogOperateType.SAFE_MANAGEMENT_EXPORT_RECTIFICATION_NOTICE);
			}
		}
		//获取并组织excel数据
		XWPFDocument doc = hiddenDangerService.getWord(type,wordType,ids, null);

		String filename;
		// 当前日期，用于导出文件名称
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String s = (type==1?"检查记录表-":"整改通知书-")+sdf.format(new Date());
		if(header.contains("Firefox")){
			//说明是火狐浏览器,使用Base64Encoder类进行编码
			filename = "=?utf-8?B?"+ Base64.encode(s.getBytes("utf-8"))+"?=";
		}else{
			//是其他浏览器,使用URLEncoder类进行编码
			filename = String.valueOf(URLEncoder.encode(s, "UTF-8"));
		}
		// 指定下载的文件名--设置响应头
		response.setHeader("Content-Disposition", "attachment;filename=" +filename+".docx");
		response.setContentType("application/msword;charset=UTF-8");
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		// 写出数据输出流到页面
		OutputStream output = response.getOutputStream();
		BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);
		doc.write(bufferedOutPut);
		bufferedOutPut.flush();
		bufferedOutPut.close();
		output.close();
	}

	@GetMapping("exportExcel")
	@ApiOperation("分包单位整理情况报表导出")
	@CommonOperateLogAnnotate(module = LogModule.SAFE_MANAGEMENT, desc = "")
	public void export(@RequestParam(value = "startTime",required = false) String startTime,@RequestParam(value = "endTime",required = false) String endTime, HttpServletRequest request, HttpServletResponse response) {
		Date startTimeDate = null;
		Date endTimeDate = null;
		if (StringUtils.isNotBlank(startTime)){
			startTimeDate = DateUtil.parseDateTime(startTime);
		}
		if (StringUtils.isNotBlank(endTime)){
			endTimeDate = DateUtil.parseDateTime(endTime);
		}
		List<HiddenDangerCountDTO> unitIdCount = this.hiddenDangerService.getUnitIdCount(startTimeDate,endTimeDate, null);
		unitIdCount.forEach( r ->{
			//数据转换
		});
		String keyValue = "分包单位:linkUnitName,隐患总数:totalNum,闭合数:qualifiedNum,待整改:waitRectifyNum,待复查:waitCheckNum,超期未整改:overdunNum,整改率:finishRate," +
				"及时整改率:inTimeFinishedRate";
		String title = "分包单位整理情况报表";
		String fileName = title + ".xls";
		try {
			OutputStream outputStream = OutputStreamUtil
					.getOutputStream(request, response, fileName);
			ExcelTools.exportExcel(outputStream, keyValue, unitIdCount, ExcelConstant.XLS, title);
			response.flushBuffer();
			outputStream.close();
		} catch (IOException e) {
			throw new RuntimeException("excel导出失败！IOException异常" + e.getMessage());
		} catch (Exception e) {
			throw new RuntimeException("excel导出失败！" + e.getMessage());
		}
	}
}
